<html>
    <head>
        <title>Vue实例</title>
    </head>
    <body>
        <script>

            // 一、 创建一个vue实例
                  // 每个Vue应用都是通过Vue函数创建一个新的Vue实例开始的：
                  var vm=new Vue({
                    // 选项
                  });
                  /*
                        虽然没有完全遵循MVVM模型，但是Vue的设计也受到了它的启发。
                        因此，在文档中经常使用vm(ViewModel的缩写)这个变量名来表示Vue实例。

                        当创建一个Vue实例时，你可以传入一个"选项对象"。
                        一个Vue应用由一个通过new Vue创建的的根Vue实例，以及可选的嵌套的、可复用的"组件树"组成。
                  */


            // 二、数据与方法
                  /*
                        当一个Vue实例被创建时，它将 data 对象中的所有property加入大Vue的"响应式系统"中。
                        当这些property的值发生改变时，视图将会产生"响应"，即匹配更新为新的值。
                  */
                        // 我们的数据对象：
                            var data={a:1};

                        // 该对象被加入到一个Vue实例中：
                            var vm1= new Vue({
                                data:data
                            });

                        // data中的property被加入到Vue对象(实例)的响应系统，成为Vue对象的property.
                        // 所以以下表达式值为真
                            vm1.a===data.a;  // true
                        
                        // 设置 vue.property 也会影响到原始数据
                            vm1.a=2;
                            data.a; // =>2
                        
                        // 反之亦然
                            data.a=3;
                            vm1.a; // =>3

                   /*
                        当这些数据改变时，视图会进行重新渲染。
                        值得注意的是，只有当实例被创建时就已经存在于data中的property才是"响应式"的。
                        也就是说，如果你添加一个新的property：    
                   */  
                            vm1.b=5;
                         /*
                            那么对b的改动不会触发任何视图的更新。
                            如果你知道你会在晚些时候需要一个porperty,但是一开始它为空或不存在，那么你仅仅需要设置一个初始值。
                         */
                         // eg：
                             var data= {
                                        newTodoText: '',
                                        visitCount: 0,
                                        hideCompletedTodos: false,
                                        todos: [],
                                        error: null
                                }
                        // 这里唯一的例外是使用Object.freeze()来创建的"不可变对象"，
                        // 这也意味着这"响应系统"无法再追踪变化
                        var obj=Object.freeze({
                            a:1
                        });
                        new Vue({
                            el:'#app',
                            data:obj
                        });


                    /*
                        除了数据property,Vue实例还暴露了一些有用的实例property与方法。
                        它们都以前缀"$"开头，以便与用户定义的property区分开来
                    */
                        var data={a:1};
                        var vm=new Vue({
                            el:'#app',
                            data:data
                        });
                        vm.$data=== data; // true
                        vm.$el=== document.getElementById('app'); // true

                        // $watch是一个实例方法
                        vm.$watch('a',function(newValue,oldValue){
                            // 这个回调将在'vm.a'发生改变后调用
                        })

                
                        
            // 实例生命周期钩子：
                    /*
                        每个Vue实例在被创建时都要记你过一系列的初始化过程-----例如，需要设置数据监听、编译模板、将实例挂载到DOM，并在数据发生改变时更新DOM等。
                        同时，在这个过程中也会运行一些叫做"生命周期钩子"的函数。
                        这给了用户在不同阶段添加自己的代码的机会。
                    */
                        // 比如， created钩子可以用来在一个实例创建之后执行代码：
                            new Vue({
                                data:{
                                    a:1
                                },
                                created:function(){
                                    // 'this'指向 vm实例 
                                }

                            });
                    /*
                        也有一些其他的钩子，在实例生命周期的不同阶段被调用,如： mounted、updated 的 destroyed.
                        生命周期钩子的 this 上下文指向调用它的实例。
                   */
                    
                    /*
                        ★、特别注意：
                                不要再选项的property或者回调上使用"箭头函数"，
                                eg:
                                    created:()=>console.log(this.a)
                                    或者
                                    vm.$watch('a',newValue=>this.myMethod())
                                不要这样用，因为“箭头函数”没有this，this会作为变量一直向上升级词法作用域，知道找到为止，经常导致
                                    Uncaught TypeError: Cannot read property of undefined 
                                    或
                                    Uncaught TypeError: this.myMethod is not a function 之类的错误。
                    */
        </script>   
    </body>
</html>